/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.reddys.rad.inventory.controller;

import com.reddys.rad.inventory.db.Purchase;
import com.reddys.rad.inventory.db.PurchaseDetails;
import com.reddys.rad.inventory.db.PurchaseOrderDetails;
import com.reddys.rad.inventory.db.PurchaseReturn;
import com.reddys.rad.inventory.db.PurchaseReturnDetails;
import com.reddys.rad.inventory.db.Stock;
import com.reddys.rad.inventory.db.StockDetails;
import com.reddys.rad.inventory.db.Vendor;
import com.reddys.rad.inventory.service.PurchaseOrderService;
import com.reddys.rad.inventory.service.PurchaseReturnService;
import com.reddys.rad.inventory.utils.EntityManagerImpl;
import com.reddys.rad.inventory.utils.Utilities;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.util.Callback;
import javax.persistence.EntityManager;

/**
 * FXML Controller class
 *
 * @author REDDYS
 */
public class PurchaseReturnController implements Initializable {
    EntityManager em;
    private  ObservableList productList =  FXCollections.observableArrayList();
      private  ObservableList data =  FXCollections.observableArrayList();
       private  ObservableList vendorList =  FXCollections.observableArrayList();
    @FXML
    TableView tableView;
    
    @FXML
    ComboBox vendiorID;
    
    @FXML
    ComboBox purchaseID;
    
    @FXML
    TextField purchaseReturnID;
    
    @FXML
    TextField purchaseReturnDescription;
    
    @FXML
    TextField purchaseDate;
    
    @FXML
    TextField remarks;
        
    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
         productList = new PurchaseReturnService().getPuschaseList();
         purchaseID.getItems().addAll(productList);
         vendorList = new PurchaseOrderService().getVendorList();
         vendiorID.getItems().addAll(vendorList);
         tableView.setEditable(true);
         purchaseReturnID.setDisable(true);
    
           purchaseID.focusedProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) {
                if (purchaseID.getSelectionModel()!=null) {
                   Purchase purchase = (Purchase) purchaseID.getSelectionModel().getSelectedItem();
                   data =  FXCollections.observableArrayList();
                   if(purchase!=null &&!Utilities.isNull(purchase.getPurchaseId())){
                       System.out.println(purchase.getPurchaseId());
                       ObservableList<PurchaseDetails> list= FXCollections.observableArrayList();
                       list = getPurchaseReturnService().getPurchaseDetailsList(purchase.getPurchaseId());
                        for(PurchaseDetails purchaseDetails:list){
                            ObservableList list1= FXCollections.observableArrayList();
                           list1.add(purchaseDetails.getProductCategoryDescription());
                           list1.add(purchaseDetails.getProductId());
                          list1.add("");
                          list1.add("");
                          list1.add(purchaseDetails.getQuantity().toString());
                           list1.add(purchaseDetails.getUom());
                          list1.add(purchaseDetails.getUnitPrice()!=null?purchaseDetails.getUnitPrice().toString():"0.0");
                          list1.add("");
                          list1.add("");
                          list1.add("");
                           data.add(list1);
                         } 
                       tableView.getItems().clear();
                        tableView.setItems(data);
                   }
                }
            }
        });
        purchaseID.setOnMouseReleased(new EventHandler() {
 
           @Override
           public void handle(Event t) {
                Purchase purchase = (Purchase) purchaseID.getSelectionModel().getSelectedItem();
                  data =  FXCollections.observableArrayList();
                   if(purchase!=null && !Utilities.isNull(purchase.getPurchaseId())){
                        System.out.println(purchase.getPurchaseId());
                   ObservableList list = getPurchaseReturnService().getPurchaseDetailsList(purchase.getPurchaseId());
                       for(int i=0;i<list.size();i++){
                          PurchaseDetails purchaseDetails = (PurchaseDetails) list.get(i);
                          ObservableList list1 = FXCollections.observableArrayList();
                          list1.add(purchaseDetails.getProductCategoryId());
                           list1.add(purchaseDetails.getProductId());
                          list1.add("");
                          list1.add("");
                          list1.add(purchaseDetails.getQuantity().toString());
                           list1.add(purchaseDetails.getUom());
                           list1.add(purchaseDetails.getUnitPrice()!=null?purchaseDetails.getUnitPrice().toString():"0.0");
                          list1.add("");
                          list1.add("");
                          list1.add("");
                          data.add(list1);
                       }
                   //    log.info("data--->"+data);
                       System.out.println(data);
                       tableView.getItems().clear();
                        tableView.setItems(data);
                   }
           }
        });
       loadTableColumns(tableView);
      // addEmptyRows();
    }    
    
        private void loadTableColumns(TableView tableView) {
   //     tableView.setEditable(true);
       TableColumn productCategory = new TableColumn("Product Category");
        productCategory.setMinWidth(100);
        Callback<TableColumn, TableCell> cellFactory =
             new Callback<TableColumn, TableCell>() {
                 public TableCell call(TableColumn p) {
                    return new EditingCell();
                 }
             };
         productCategory.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<String>,String>, ObservableValue<String>>(){

            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList<String>, String> cdf) {
              return new SimpleStringProperty( 
                      cdf.getValue().get(0)!=null?cdf.getValue().get(0).toString():"");
            }
           

           
        });
       TableColumn productID = new TableColumn("Product ID");
        productID.setMinWidth(100);
       productID.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<String>,String>, ObservableValue<String>>(){

            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList<String>, String> cdf) {
              return new SimpleStringProperty( 
                      cdf.getValue().get(1).toString());
            }
              });

        TableColumn productName = new TableColumn("Product Name");
        productName.setMinWidth(200);
        productName.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<String>,String>, ObservableValue<String>>(){

            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList<String>, String> cdf) {
              return new SimpleStringProperty( 
                      cdf.getValue().get(2)!=null?cdf.getValue().get(2).toString():"");
            }  });
       // productName.setCellFactory(cellFactory);
        
        TableColumn itemCode = new TableColumn("Item Code");
        itemCode.setMinWidth(100);
        //itemCode.setCellFactory(cellFactory);
    itemCode.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<String>,String>, ObservableValue<String>>(){

            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList<String>, String> cdf) {
              return new SimpleStringProperty( 
                      cdf.getValue().get(3).toString());
            }  });
        TableColumn quantity = new TableColumn("Quantity");
        quantity.setMinWidth(100);
            quantity.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<String>,String>, ObservableValue<String>>(){

            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList<String>, String> cdf) {
              return new SimpleStringProperty( 
                      cdf.getValue().get(4)!=null?cdf.getValue().get(4).toString():"");
            }  });
        
        TableColumn uom = new TableColumn("Uom");
        uom.setMinWidth(100);
            uom.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<String>,String>, ObservableValue<String>>(){

            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList<String>, String> cdf) {
              return new SimpleStringProperty( 
                      cdf.getValue().get(5).toString());
            }  });
        TableColumn unitPrice = new TableColumn("Unit Price");
        unitPrice.setMinWidth(100);

            unitPrice.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<String>,String>, ObservableValue<String>>(){

            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList<String>, String> cdf) {
              return new SimpleStringProperty( 
                      cdf.getValue().get(6).toString());
            }  });
        TableColumn returned = new TableColumn("Returned");
        returned.setMinWidth(100);
        returned.setCellFactory( new Callback<TableColumn, TableCell>() {
                 public TableCell call(TableColumn p) {
                    return new EditingCell("Returned");
                 }
         });
        TableColumn returnedremarks = new TableColumn("Remarks");
        returnedremarks.setMinWidth(100);

        returnedremarks.setCellFactory( new Callback<TableColumn, TableCell>() {
                 public TableCell call(TableColumn p) {
                    return new EditingCell("remarks");
                 }
             });
        
        TableColumn subTotal = new TableColumn("Sub Total");
        subTotal.setMinWidth(100);
        tableView.getColumns().addAll(productCategory, productID, productName,itemCode, quantity, uom,unitPrice,subTotal,returned, returnedremarks);
        //tableView.getItems().addAll(data);
 
    }

      
    private void updatePurchase(String purchaseId,Double returnedAmount,EntityManager em) {
        Purchase purchase = getPurchaseReturnService().getPurchaseByPurchaseId(purchaseId);
        if(purchase!=null){
        purchase.setTotalAmount(purchase.getTotalAmount()!=null?purchase.getTotalAmount()-returnedAmount:new Double("0.0")-returnedAmount);
         purchase.setNetAmount(purchase.getNetAmount()!=null?purchase.getNetAmount()-returnedAmount:new Double("0.0")-returnedAmount);
        em.merge(purchase);
        }
    }
    
    private void updatePurchaseDetail(String purchaseId, String productId, Double rejectedQuantity, Double returnedAmount, EntityManager em) {
        PurchaseDetails purchaseDetail = getPurchaseReturnService().getPurchaseDetailByPurchaseId(purchaseId,productId);
        if(purchaseDetail!=null){
        purchaseDetail.setRejected(purchaseDetail.getRejected()!=null?purchaseDetail.getRejected()+rejectedQuantity:new Double("0.0")+rejectedQuantity);
        purchaseDetail.setQuantity(purchaseDetail.getQuantity()!=null?purchaseDetail.getQuantity()-rejectedQuantity:new Double("0.0") - rejectedQuantity);
        purchaseDetail.setNetPrice(purchaseDetail.getNetPrice()!=null?purchaseDetail.getNetPrice()-returnedAmount:new Double("0.0") - returnedAmount);
        em.merge(purchaseDetail);
        updatePurchaseOrder(purchaseId,productId,rejectedQuantity,em);
        }
    }
    
    private void updatePurchaseOrder(String purchaseId, String productId,Double rejectedQuantity,EntityManager em) {
        PurchaseOrderDetails purchaseOrderDetails = getPurchaseReturnService().getPurchaseOrderDetailByPurchaseId(purchaseId,productId);
        if(purchaseOrderDetails!=null){
        purchaseOrderDetails.setQuantityRemaining(purchaseOrderDetails.getQuantityRemaining()!=null?purchaseOrderDetails.getQuantityRemaining()+rejectedQuantity:new Double("0.0")+rejectedQuantity);
        purchaseOrderDetails.setQuantityReceived(purchaseOrderDetails.getQuantityReceived()!=null?purchaseOrderDetails.getQuantityReceived()-rejectedQuantity:new Double("0.0") - rejectedQuantity);
        em.merge(purchaseOrderDetails);
        }
    }

                 class EditingCell extends TableCell<Object, String> {
        private String columnName ;
        private TextField textField;

        public EditingCell() {
        }
       public EditingCell(String columnName ) {
           this.columnName = columnName;
        }
 
        @Override
        public void startEdit() {
           
                super.startEdit();
                createTextField();
                setText(null);
                setGraphic(textField);
                textField.selectAll();

        }
 
        @Override
        public void cancelEdit() {
            super.cancelEdit();
 
            setText((String) getItem());
            setGraphic(null);
        }
 
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
 
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(getString());
                    }
                    setText(null);
                    setGraphic(textField);
                } else {
                    setText(getString());
                    setGraphic(null);
                }
            }
        }
     public Property<String> inputText()
    {
        return textField.textProperty();
    }

        private void createTextField() {
            textField = new TextField(getString());
            textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()* 2);
            textField.focusedProperty().addListener(new ChangeListener<Boolean>(){

                @Override
                public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
                                           ObservableList tableData = (ObservableList) tableView.getSelectionModel().getSelectedItem();
                System.out.println("tableData"+tableData);
                    System.out.println("createtext"+textField.getText());
                    if(columnName.equalsIgnoreCase("Quantity")){

                        tableData.set(5, textField.getText());
                    }else if(columnName.equalsIgnoreCase("UOM")){
                        tableData.set(6, textField.getText());
                    }else if(columnName.equalsIgnoreCase("UnitPrice")){
                        tableData.set(8, textField.getText());
                    }else if(columnName.equalsIgnoreCase("Sub Total")){
                     tableData.set(7, textField.getText());
                    }
                    else if(columnName.equalsIgnoreCase("Returned")){
                      tableData.set(8, textField.getText());
                    }else if(columnName.equalsIgnoreCase("Remarks")){
                     tableData.set(9, textField.getText());
                    }

                }
                
            });

         }
 
        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
     }
     public PurchaseReturnService getPurchaseReturnService(){
        PurchaseReturnService purchaseReturnrvice = new PurchaseReturnService();
        return purchaseReturnrvice;
    }
     
             @FXML
        public PurchaseReturn save(){
            PurchaseReturn purchaseReturn = new PurchaseReturn();
            if(validateSave()){
             em = EntityManagerImpl.getEntityManager();
            EntityManagerImpl.beginTransaction(em);
           
            try{
            purchaseReturn.setPurchaseReturnDescription(purchaseReturnDescription.getText());
           //  purchase.setPurchaseDate(purchaseDescription.getText());
            Purchase purchase = (Purchase) purchaseID.getSelectionModel().getSelectedItem();
            purchaseReturn.setPurchaseId(purchase.getPurchaseId());
            Vendor vendor = (Vendor) vendiorID.getSelectionModel().getSelectedItem();
            purchaseReturn.setVendorId(vendor.getVendorid());
            purchaseReturn.setRemarks(remarks.getText());
            getPurchaseReturnService().saveReturn(purchaseReturn,em);
            ObservableList purchaseReturnDetailsList = tableView.getItems();
            System.out.println("tableDtata ------------------->"+purchaseReturnDetailsList);
            Double toBeReturnedAmount = 0.0;
            for(int i=0;i<purchaseReturnDetailsList.size();i++){
                 ObservableList purchaseReturnDetailRowList = (ObservableList) purchaseReturnDetailsList.get(i);
                PurchaseReturnDetails purchaseDetails = new PurchaseReturnDetails();
               purchaseDetails.setPurchaseReturnId(purchaseReturn.getPurchaseReturnId());
                purchaseDetails.setProductId((String) purchaseReturnDetailRowList.get(1));
               // purchaseDetails.setProductCategoryId((String) purchaseReturnDetailRowList.get(0));
               // purchaseDetails.setBatchCode((String) purchaseRowList.get(1));
                purchaseDetails.setQuantityReceived(Double.valueOf(Utilities.isNull(purchaseReturnDetailRowList.get(4).toString())?"0.0":purchaseReturnDetailRowList.get(4).toString()));
                purchaseDetails.setQuantityRejected(Double.valueOf(purchaseReturnDetailRowList.get(8).toString()));
                purchaseDetails.setUom((String) purchaseReturnDetailRowList.get(5));
                purchaseDetails.setRejectedRemarks((String) purchaseReturnDetailRowList.get(9));
               
               getPurchaseReturnService().saveReturnDetaild(purchaseDetails,em);
               Double rteturnedAmount = Double.valueOf(Utilities.isNull(purchaseReturnDetailRowList.get(6).toString())?"0.0":purchaseReturnDetailRowList.get(6).toString());
                toBeReturnedAmount = toBeReturnedAmount +(Double.valueOf(purchaseReturnDetailRowList.get(8).toString()) * Double.valueOf(Utilities.isNull(purchaseReturnDetailRowList.get(6).toString())?"0.0":purchaseReturnDetailRowList.get(6).toString()));
                  updatePurchaseDetail(purchaseReturn.getPurchaseId(),purchaseDetails.getProductId(),purchaseDetails.getQuantityRejected(),rteturnedAmount,em);
              Stock stock = getPurchaseReturnService().getStock(purchaseDetails.getProductId());
               if(null==stock){
                 stock = new Stock();
                 stock.setProductId(purchaseDetails.getProductId()); 
              }
                  stock.setPurchasedQuantity(stock.getPurchasedQuantity()!=null?stock.getPurchasedQuantity()-purchaseDetails.getQuantityRejected():new Double(0.0)-purchaseDetails.getQuantityRejected());
                  stock.setAvailableQuantity(stock.getAvailableQuantity()!=null?stock.getAvailableQuantity()-purchaseDetails.getQuantityRejected():new Double(0.0)-purchaseDetails.getQuantityRejected());
                  Utilities.updateStock(stock,em); 


            }
            updatePurchase(purchase.getPurchaseId(),toBeReturnedAmount,em);
                StockDetails stockDetails = new StockDetails();
                stockDetails.setStockDetailDescription(purchaseReturn.getPurchaseReturnDescription());
                stockDetails.setTransactionId(purchaseReturn.getPurchaseReturnId());
                stockDetails.setTransactionDate(Utilities.getCurrentDate());
                stockDetails.setTransactionType("purchase return");
               Utilities.updateStockDetails(stockDetails,em);
               EntityManagerImpl.commitTransaction(em);
               purchaseReturnID.setText(purchaseReturn.getPurchaseReturnId());
                Utilities.createDialog("Transaction completed successfully");
            }catch(Exception e){
                e.printStackTrace();
                //log.info(e.getMessage());
                 EntityManagerImpl.rollbackTransaction(em);
                Utilities.createDialog("Transaction Failed");
            }
            }
            return purchaseReturn;
        }

                 private boolean validateSave() {
        boolean purchaseDetailsBoolean = true;
        if(Utilities.isNull(purchaseReturnDescription.getText())){
             Utilities.createDialog("Please enter Purchase Return Description");
            return false;
        }
         
        if(purchaseID.getSelectionModel()!=null){
             Purchase purchase = (Purchase) purchaseID.getSelectionModel().getSelectedItem();
            if(null == purchase){
            Utilities.createDialog("Please Select Purchase ID");
            return false;
            }
        }else{
             Utilities.createDialog("Please Select Purchase ID");
            return false;
        }
        
                 
        if(vendiorID.getSelectionModel()!=null){
             Vendor vendor = (Vendor) vendiorID.getSelectionModel().getSelectedItem();
            if(null == vendor){
            Utilities.createDialog("Please Select Vendor ID");
            return false;
            }
        }else{
             Utilities.createDialog("Please Select Vendor ID");
            return false;
        }
        for(int i =0;i<tableView.getItems().size();i++){
                ObservableList purchaseRowList = (ObservableList) tableView.getItems().get(i);

        if(!Utilities.isNull(purchaseRowList.get(1).toString())){
            purchaseDetailsBoolean = false;
            if(null ==purchaseRowList.get(8)) {
                Utilities.createDialog("Please enter Returned Quantity");
                return false;
            }
            if(Utilities.isNull(purchaseRowList.get(9).toString())) {
                Utilities.createDialog("Please enter Remarks");
                return false;
            }
         }
        }
        if(purchaseDetailsBoolean){
             Utilities.createDialog("Please Add Atleast one Product");
            return false;
        }
        System.out.println(tableView.getItems().size());
        return true;
    }

}
